package org.jeecg.modules.workflow.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.utils.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.util.UUIDGenerator;
import org.jeecg.modules.function.entity.SysFuncBase;
import org.jeecg.modules.function.entity.SysFuncGroup;
import org.jeecg.modules.function.service.ISysFuncBaseService;
import org.jeecg.modules.function.service.ISysFuncGroupService;
import org.jeecg.modules.workflow.entity.*;
import org.jeecg.modules.workflow.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description: 工作流节点操作
 * @author: wufanxin
 * @date: 2021-06-11
 * @version: V1.0
 */
@Slf4j
@RestController
@RequestMapping("/sys/workflowNode")
@Api(tags = "工作流基础")
public class WorkFlowNodeController {
	@Autowired
	private IWorkFlowParentNodeService workFlowParentNodeService;

	@Autowired
	private IWorkFlowChildNodeService workFlowChildNodeService;

	@Autowired
	private IWorkFlowChildNodeAssignDeptService workFlowChildNodeAssignDeptService;
	@Autowired
	private IWorkFlowChildNodeAssignRoleService workFlowChildNodeAssignRoleService;

	@Autowired
	private IWorkFlowChildNodeAssignPersonService workFlowChildNodeAssignPersonService;

	@Autowired
	private ISysFuncBaseService sysFuncBaseService;

	@Autowired
	private ISysFuncGroupService sysFuncGroupService;

	@Autowired
	private IWorkFlowBaseAssignService workFlowBaseAssignService;

	@Autowired
	private IWorkFlowChildNodeGroupAssignService workFlowChildNodeGroupAssignService;

	@Autowired
	private IWorkFlowChildNodeFuncAssignService workFlowChildNodeFuncAssignService;


	/**
	 * 新增一级节点
	 *
	 * @param workFlowParentNode
	 * @param req
	 * @return
	 */
	@ApiOperation(value = "工作流节点操作-新增一级节点", notes = "工作流节点操作-新增一级节点")
	@GetMapping(value = "/addParentNode")
	public Result<?> addParentNode(WorkFlowParentNode workFlowParentNode, HttpServletRequest req) {
		if(StringUtils.isEmpty(workFlowParentNode.getNodeId())){
			workFlowParentNode.setNodeId(UUIDGenerator.generate());
			workFlowParentNodeService.save(workFlowParentNode);
		}else{
			UpdateWrapper<WorkFlowParentNode> updateWrapper = new UpdateWrapper<>();
			updateWrapper.set("node_name",workFlowParentNode.getNodeName());
			updateWrapper.set("op_type",workFlowParentNode.getOpType());
			updateWrapper.set("back_node_id",workFlowParentNode.getBackNodeId());
			updateWrapper.set("sort",workFlowParentNode.getSort());
			updateWrapper.eq("node_id",workFlowParentNode.getNodeId());
			workFlowParentNodeService.update(updateWrapper);
		}

		return Result.ok();
	}




	/**
	 * 新增二级节点
	 *
	 * @param workFlowChildNode
	 * @param req
	 * @return
	 */
	@ApiOperation(value = "工作流节点操作-新增二级节点", notes = "工作流节点操作-新增二级节点")
	@GetMapping(value = "/addChildNode")
	public Result<?> addChildNode(WorkFlowChildNode workFlowChildNode, HttpServletRequest req) {
		if(StringUtils.isEmpty(workFlowChildNode.getNodeId())) {
			workFlowChildNode.setNodeId(UUIDGenerator.generate());
			workFlowChildNodeService.save(workFlowChildNode);
		}else{
			UpdateWrapper<WorkFlowChildNode> updateWrapper = new UpdateWrapper<>();
			updateWrapper.set("node_name",workFlowChildNode.getNodeName());
			if(!StringUtils.isEmpty(workFlowChildNode.getPerformType())){
				updateWrapper.set("perform_type",workFlowChildNode.getPerformType());
			}
			updateWrapper.set("parent_node_id",workFlowChildNode.getParentNodeId());
			updateWrapper.eq("node_id",workFlowChildNode.getNodeId());
			workFlowChildNodeService.update(updateWrapper);
		}

		return Result.ok(workFlowChildNode);
	}



	/**
	 * 查询所有一级节点(回退下拉使用)
	 *
	 * @param workFlowParentNode
	 * @param req
	 * @return
	 */
	@ApiOperation(value = "工作流节点操作-查询所有一级节点(回退下拉使用)", notes = "工作流节点操作-查询所有一级节点(回退下拉使用)")
	@GetMapping(value = "/selectParentNodeByWorkflowId")
	public Result<?> selectParentNodeByWorkflowId(WorkFlowParentNode workFlowParentNode, HttpServletRequest req) {
		QueryWrapper<WorkFlowParentNode> queryWrapper = new QueryWrapper<>();
		queryWrapper.select("node_id as value", "node_name as label");
		queryWrapper.eq("workflow_id",workFlowParentNode.getWorkflowId());
		queryWrapper.orderByAsc("sort");
		List<WorkFlowParentNode> parentNodes = workFlowParentNodeService.list(queryWrapper);
		return Result.ok(parentNodes);
	}




	/**
	 * 查询父节点所有信息（列表，树展示）
	 *
	 * @param workFlowParentNode
	 * @param req
	 * @return
	 */
	@ApiOperation(value = "工作流节点操作-查询父节点所有信息（列表，树展示）", notes = "工作流节点操作-查询父节点所有信息（列表，树展示）")
	@GetMapping(value = "/selectTreeParentNodeByWorkflowId")
	public Result<?> selectTreeParentNodeByWorkflowId(WorkFlowParentNode workFlowParentNode, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
											   @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) {
		Page<WorkFlowParentNode> page = new Page<WorkFlowParentNode>(pageNo, pageSize);
		IPage<WorkFlowParentNode> pageList = workFlowParentNodeService.selectTreeParentNodeByWorkflowId(page, workFlowParentNode);
		List<WorkFlowParentNode> list = pageList.getRecords();
		list.stream().forEach(item->{

			QueryWrapper<WorkFlowChildNode> queryWrapper = new QueryWrapper<>();
			queryWrapper.eq("parent_node_id",item.getNodeId());
			List<WorkFlowChildNode> childList = workFlowChildNodeService.list(queryWrapper);
			item.setChildren(childList);

		});
		return Result.ok(pageList);
	}


	/**
	 * 查询子节点所有信息（列表，树展示）
	 *
	 * @param workFlowChildNode
	 * @param req
	 * @return
	 */
	@ApiOperation(value = "工作流节点操作-查询子节点所有信息（列表，树展示）", notes = "工作流节点操作-查询子节点所有信息（列表，树展示）")
	@GetMapping(value = "/selectTreeChildNodeByWorkflowId")
	public Result<?> selectTreeChildNodeByWorkflowId(WorkFlowChildNode workFlowChildNode, HttpServletRequest req) {
		QueryWrapper<WorkFlowChildNode> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("parent_node_id",workFlowChildNode.getParentNodeId());
		List<WorkFlowChildNode> childList = workFlowChildNodeService.list(queryWrapper);
		return Result.ok(childList);

	}



	/**
	 * 二级节点分配人员和部门信息
	 *
	 * @param reqMap
	 *			assignType : 0 部门 1 人
	 *  		assignList: 部门id或者人的id的集合
	 *  		nodeId
	 *  		workFlowId
	 * @param req
	 * @return
	 */
	@ApiOperation(value = "工作流节点操作-二级节点分配人员和部门信息", notes = "工作流节点操作-二级节点分配人员和部门信息")
	@PostMapping(value = "/childNodeAssignDeptAndPerson")
	public Result<?> childNodeAssignDeptAndPerson(@RequestBody Map<String,Object> reqMap, HttpServletRequest req) {


		QueryWrapper<WorkFlowChildNodeAssignDept> deptQueryWrapper = new QueryWrapper<>();
		deptQueryWrapper.eq("node_id",reqMap.get("nodeId"));
		workFlowChildNodeAssignDeptService.remove(deptQueryWrapper);

		QueryWrapper<WorkFlowChildNodeAssignPerson> personQueryWrapper = new QueryWrapper<>();
		personQueryWrapper.eq("node_id",reqMap.get("nodeId"));
		workFlowChildNodeAssignPersonService.remove(personQueryWrapper);


		QueryWrapper<WorkFlowChildNodeAssignRole> roleQueryWrapper = new QueryWrapper<>();
		roleQueryWrapper.eq("node_id",reqMap.get("nodeId"));
		workFlowChildNodeAssignRoleService.remove(roleQueryWrapper);


		//根据节点名称，更新二级节点的assignType字段
		UpdateWrapper<WorkFlowChildNode> updateWapper = new UpdateWrapper<>();
		updateWapper.set("assign_type",reqMap.get("assignType"));
		updateWapper.eq("node_id",reqMap.get("nodeId"));
		workFlowChildNodeService.update(updateWapper);

		Map<String,Object> assignInfo = (Map<String, Object>) reqMap.get("assignList");
		//根据assignType的类型,觉得更新数据
		if(reqMap.get("assignType").equals("0")){
			List<WorkFlowChildNodeAssignDept> deptList = new ArrayList<>();
			List<String> departs = (List<String>)assignInfo.get("departs");
			if(null != departs && departs.size() > 0){
				departs.stream().forEach(item->{
					WorkFlowChildNodeAssignDept workFlowChildNodeAssignDept = new WorkFlowChildNodeAssignDept();
					workFlowChildNodeAssignDept.setAssignInfo(item);
					workFlowChildNodeAssignDept.setNodeId(reqMap.get("nodeId").toString());
					workFlowChildNodeAssignDept.setWorkflowId(reqMap.get("workflowId").toString());
					deptList.add(workFlowChildNodeAssignDept);
				});
				workFlowChildNodeAssignDeptService.saveBatch(deptList);
			}


			List<WorkFlowChildNodeAssignRole> roleList = new ArrayList<>();
			List<String> roles = (List<String>)assignInfo.get("roles");
			if(null != roles && roles.size() > 0){
				roles.stream().forEach(item->{
					WorkFlowChildNodeAssignRole workFlowChildNodeAssignRole = new WorkFlowChildNodeAssignRole();
					workFlowChildNodeAssignRole.setAssignInfo(item);
					workFlowChildNodeAssignRole.setNodeId(reqMap.get("nodeId").toString());
					workFlowChildNodeAssignRole.setWorkflowId(reqMap.get("workflowId").toString());
					roleList.add(workFlowChildNodeAssignRole);
				});
				workFlowChildNodeAssignRoleService.saveBatch(roleList);
			}

		}else{
			List<WorkFlowChildNodeAssignPerson> personList = new ArrayList<>();
			List<String> users = (List<String>)assignInfo.get("users");
			if(null != users && users.size() > 0) {
				users.stream().forEach(item -> {
					WorkFlowChildNodeAssignPerson workFlowChildNodeAssignPerson = new WorkFlowChildNodeAssignPerson();
					workFlowChildNodeAssignPerson.setAssignInfo(item);
					workFlowChildNodeAssignPerson.setNodeId(reqMap.get("nodeId").toString());
					workFlowChildNodeAssignPerson.setWorkflowId(reqMap.get("workflowId").toString());
					personList.add(workFlowChildNodeAssignPerson);
				});
				workFlowChildNodeAssignPersonService.saveBatch(personList);
			}
		}

		return Result.ok();
	}




	/**
	 * 查询展示功能组以及功能
	 *
	 * @param req
	 * @return
	 */
	@ApiOperation(value = "工作流节点操作-查询展示功能组以及功能", notes = "工作流节点操作-查询展示功能组以及功能")
	@GetMapping(value = "/selectAviFunc")
	public Result<?> selectAviFunc(HttpServletRequest req) {
		List<SysFuncGroup> groupList = sysFuncGroupService.list();

		groupList.stream().forEach(item->{
			QueryWrapper<SysFuncBase> queryWrapper = new QueryWrapper<>();
			queryWrapper.eq("func_group",item.getFuncGroupCode());
			queryWrapper.orderByAsc("func_group_order");
			List<SysFuncBase> funList = sysFuncBaseService.list(queryWrapper);
			item.setFuncList(funList);
		});
		return Result.ok(groupList);
	}


	/**
	 * 工作流节点操作-根据工作流的配置，查询可以选择的人或者部门
	 * @param req
	 * @return
	 */
	@ApiOperation(value = "工作流节点操作-（废弃）查询可以选择的人或者部门", notes = "工作流节点操作-查询可以选择的人或者部门")
	@GetMapping(value = "/selectAviDeptOrPersonByWorkflowId")
	public Result<?> selectAviDeptOrPersonByWorkflowId(WorkFlowChildNode workFlowChildNode,HttpServletRequest req) {

		//根据工作流获取可以选择的部门id
		QueryWrapper<WorkFlowBaseAssign> queryWrapper = new QueryWrapper<>();
		List<WorkFlowBaseAssign> assignDeptList = workFlowBaseAssignService.list(queryWrapper);

		//根据查询的可选部门数据查询部门和人
		if(workFlowChildNode.getAssignType().equals("0")){
			// TODO: 2021/6/10  查询部门，参考现在有的结构
		}else{
			// TODO: 2021/6/10 查询人，参考现在有结构
		}
		return Result.ok();
	}





	/**
	 * 工作流节点操作-节点绑定功能组和功能
	 * @param req
	 * @return
	 */
	@ApiOperation(value = "工作流节点操作-节点绑定功能组和功能", notes = "工作流节点操作-节点绑定功能组和功能")
	@PostMapping(value = "/bindNodeFuncAndGroup")
	public Result<?> bindNodeFuncAndGroup(@RequestBody Map<String,Object> param,HttpServletRequest req) {

		QueryWrapper<ChildNodeGroupAssign> groupQueryWrapper = new QueryWrapper<>();
		groupQueryWrapper.eq("node_id",param.get("nodeId"));
		workFlowChildNodeGroupAssignService.remove(groupQueryWrapper);

		QueryWrapper<ChildNodeFuncAssign> funcQueryWrapper = new QueryWrapper<>();
		funcQueryWrapper.eq("node_id",param.get("nodeId"));
		workFlowChildNodeFuncAssignService.remove(funcQueryWrapper);

		//获取参数
		String nodeId = param.get("nodeId").toString();
		List<Map<String,Object>> groupList = (List<Map<String,Object>>)param.get("funcGroup");

		//根据参数获取封装功能组列表和功能列表
		List<ChildNodeGroupAssign> groupAssignList  = new ArrayList<>();
		List<ChildNodeFuncAssign> funcAssignList  = new ArrayList<>();

		groupList.stream().forEach(item ->{
			ChildNodeGroupAssign groupAssign = new ChildNodeGroupAssign();
			groupAssign.setGroupId(item.get("groupId").toString());
			groupAssign.setNodeId(nodeId);
			groupAssignList.add(groupAssign);
			List<String> funcList = (List<String>)item.get("funcList");
			funcList.stream().forEach(func->{
				ChildNodeFuncAssign funcAssign = new ChildNodeFuncAssign();
				funcAssign.setFuncId(func);
				funcAssign.setGroupId(item.get("groupId").toString());
				funcAssign.setNodeId(nodeId);
				funcAssignList.add(funcAssign);
			});
		});
		workFlowChildNodeGroupAssignService.saveBatch(groupAssignList);
		workFlowChildNodeFuncAssignService.saveBatch(funcAssignList);
		return Result.ok();
	}





	/**
	 * 工作流节点操作-删除节点
	 * @param req
	 * @param nodeId
	 * @param type  0 1级，1 2级
	 * @return
	 */
	@ApiOperation(value = "工作流节点操作-删除节点", notes = "工作流节点操作-删除节点")
	@GetMapping(value = "/deleteNode")
	public Result<?> deleteNode(@RequestParam String  nodeId,@RequestParam String type, HttpServletRequest req) {

		if(type.equals("0")){
			//删除一级节点
			QueryWrapper<WorkFlowParentNode> deleteWrapper = new QueryWrapper<>();
			deleteWrapper.eq("node_id",nodeId);
			workFlowParentNodeService.remove(deleteWrapper);
		}else{
			//删除二级节点
			QueryWrapper<WorkFlowChildNode> deleteWrapper = new QueryWrapper<>();
			deleteWrapper.eq("node_id",nodeId);
			workFlowChildNodeService.remove(deleteWrapper);
		}
		return Result.ok();
	}




	/**
	 * 工作流节点操作-查询二级节点分配的人或部门
	 * @param req
	 * @param nodeId
	 * @param type 0 部门，1人
	 * @return
	 */
	@ApiOperation(value = "工作流节点操作-查询二级节点分配的人或部门", notes = "工作流节点操作-查询二级节点分配的人或部门")
	@GetMapping(value = "/selectChildNodeDeptOrPersonAssign")
	public Result<?> selectChildNodeDeptOrPersonAssign(@RequestParam String  nodeId,@RequestParam String type, HttpServletRequest req) {

		Map<String,Object> retMap = new HashMap<>();
		List result = new ArrayList();
		if(type.equals("0")){
			//查询部门
			QueryWrapper<WorkFlowChildNodeAssignDept> queryWrapper = new QueryWrapper<>();
			queryWrapper.eq("node_id",nodeId);
			List<WorkFlowChildNodeAssignDept> deptList = workFlowChildNodeAssignDeptService.list(queryWrapper);
			retMap.put("departs",deptList);

			//查询角色
			QueryWrapper<WorkFlowChildNodeAssignRole> queryWrapperRole = new QueryWrapper<>();
			queryWrapperRole.eq("node_id",nodeId);
			List<WorkFlowChildNodeAssignRole> roleList = workFlowChildNodeAssignRoleService.list(queryWrapperRole);
			retMap.put("roles",roleList);
//			result = deptList;
		}else{
			//查询人
			QueryWrapper<WorkFlowChildNodeAssignPerson> queryWrapper = new QueryWrapper<>();
			queryWrapper.eq("node_id",nodeId);
			List<WorkFlowChildNodeAssignPerson> persontList = workFlowChildNodeAssignPersonService.list(queryWrapper);
			retMap.put("users",persontList);

//			result = persontList;
		}
		return Result.ok(retMap);
	}



	/**
	 * 工作流节点操作-查询节点基础信息
	 * @param req
	 * @param nodeId
	 * @param type 0 1级 1 2级
	 * @return
	 */
	@ApiOperation(value = "工作流节点操作-查询节点基础信息", notes = "工作流节点操作-查询节点基础信息")
	@GetMapping(value = "/queryNodeInfo")
	public Result<?> queryNodeInfo(@RequestParam String  nodeId,@RequestParam String type, HttpServletRequest req) {

		Object result = null;
		if(type.equals("0")){
			//查询一级
			QueryWrapper<WorkFlowParentNode> queryWrapper = new QueryWrapper<>();
			queryWrapper.eq("node_id",nodeId);
			WorkFlowParentNode parentNode = workFlowParentNodeService.getOne(queryWrapper);
			result = parentNode;
		}else{
			//查询二级
			QueryWrapper<WorkFlowChildNode> queryWrapper = new QueryWrapper<>();
			queryWrapper.eq("node_id",nodeId);
			WorkFlowChildNode childNode = workFlowChildNodeService.getOne(queryWrapper);
			result = childNode;
		}
		return Result.ok(result);
	}


	/**
	 * 工作流节点操作-查询节点配置功能
	 * @param req
	 * @param nodeId
	 * @return
	 */
	@ApiOperation(value = "工作流节点操作-查询节点配置功能", notes = "工作流节点操作-查询节点配置功能")
	@GetMapping(value = "/queryNodeFunc")
	public Result<?> queryNodeFunc(@RequestParam String  nodeId, HttpServletRequest req) {
		//查询分配的工作组
		QueryWrapper<ChildNodeGroupAssign> groupWrapper = new QueryWrapper<>();
		groupWrapper.eq("node_id",nodeId);
		List<ChildNodeGroupAssign> groupList = workFlowChildNodeGroupAssignService.list(groupWrapper);
		List<Map<String,Object>> resultList = new ArrayList<>();
		groupList.stream().forEach(group->{
			Map<String,Object> groupMap = new HashMap<>();
			groupMap.put("groupId",group.getGroupId());
			//根据nodeid和groupId查询功能
			QueryWrapper<ChildNodeFuncAssign> funcWrapper = new QueryWrapper<>();
			funcWrapper.eq("node_id",nodeId);
			funcWrapper.eq("group_id",group.getGroupId());
			List<ChildNodeFuncAssign> funcList = workFlowChildNodeFuncAssignService.list(funcWrapper);
			List<String> funcStringList = new ArrayList<>();
			funcList.stream().forEach(func->{
				funcStringList.add(func.getFuncId());
			});
			groupMap.put("funcList",funcStringList);
			resultList.add(groupMap);
		});
		return Result.ok(resultList);
	}




	/**
	 * 工作流节点操作-查询节点配置功能（任务用，按位置分组）
	 * @param req
	 * @param childNodeId
	 * @return
	 */
	@ApiOperation(value = "工作流节点操作-查询节点配置功能（任务用，按位置分组）", notes = "工作流节点操作-查询节点配置功能（任务用，按位置分组）")
	@GetMapping(value = "/queryNodeFuncTask")
	public Result<?> queryNodeFuncTask(@RequestParam String  childNodeId, HttpServletRequest req) {
		//查询分配的工作组
		QueryWrapper<ChildNodeGroupAssign> groupWrapper = new QueryWrapper<>();
		groupWrapper.eq("node_id",childNodeId);
		List<ChildNodeGroupAssign> groupList = workFlowChildNodeGroupAssignService.list(groupWrapper);
		List<Map<String,Object>> resultList = new ArrayList<>();
		List<String> groupStringList = new ArrayList<>();
		groupList.stream().forEach(group->{
			groupStringList.add(group.getGroupId());
		});
		QueryWrapper<SysFuncGroup> groupListInfoWrapper = new QueryWrapper<>();
		groupListInfoWrapper.in("func_group_code",groupStringList);
		groupListInfoWrapper.orderByAsc("sort");
		List<SysFuncGroup> groupInfoList = sysFuncGroupService.list(groupListInfoWrapper);

		groupInfoList.stream().forEach(group->{
			//获取group信息
			QueryWrapper<SysFuncGroup> groupInfoWrapper = new QueryWrapper<>();
			groupInfoWrapper.eq("func_group_code",group.getFuncGroupCode()).last(" limit 1");
			SysFuncGroup groupInfo = sysFuncGroupService.getOne(groupInfoWrapper);

			Map<String,Object> groupMap = new HashMap<>();
			groupMap.put("groupId",group.getFuncGroupCode());
			groupMap.put("postion",groupInfo.getPosition());
			groupMap.put("groupName",groupInfo.getFuncGroupName());
			//根据nodeid和groupId查询功能
			QueryWrapper<ChildNodeFuncAssign> funcWrapper = new QueryWrapper<>();
			funcWrapper.eq("node_id",childNodeId);
			funcWrapper.eq("group_id",group.getFuncGroupCode());
			List<ChildNodeFuncAssign> funcList = workFlowChildNodeFuncAssignService.list(funcWrapper);
			List<String> funcStringList = new ArrayList<>();
			funcList.stream().forEach(func->{
				funcStringList.add(func.getFuncId());
			});
			if(null != funcStringList && funcStringList.size()>0){
				QueryWrapper<SysFuncBase> baseInfoWrapper = new QueryWrapper<>();
				baseInfoWrapper.in("func_code",funcStringList).orderByAsc("func_group_order");
				List<SysFuncBase> funcBases = sysFuncBaseService.list(baseInfoWrapper);
				groupMap.put("funcList",funcBases);
				resultList.add(groupMap);
			}

		});
		return Result.ok(resultList);
	}



}
